package My

import "fmt"

var (
	getTableNameSql = func(o, s, t string) string {
		return fmt.Sprintf("select table_NAME as `tableName` from %v where TABLE_TYPE = 'BASE TABLE'  AND table_schema ='%v' %v", o, s, getLikeTable(t))
	}
	getSeqNameSql = func(o, s, t string) string {
		return fmt.Sprintf("select name from %v where  db ='%v' %v", o, s, getLikeSeqName(t))
	}
	getTableExistenceSql = func(o, s, t string) string {
		return fmt.Sprintf("select table_name from %v where TABLE_TYPE = 'BASE TABLE'  AND table_schema ='%v'  and table_NAME = '%v'", o, s, t)
	}
	getSeqExistenceSql = func(o, s, t string) string {
		return fmt.Sprintf("select name from %v where db = '%v' AND name ='%v'", o, s, t)
	}
	getSchemaNameSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT SCHEMA_NAME  FROM %v WHERE SCHEMA_NAME = '%v'", o, s)
	}
	getTableCommentSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT TABLE_COMMENT as `comment` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME='%v'", o, s, t)
	}
	getColumnCommentSql = func(o, s, t string) string {
		return fmt.Sprintf("select COLUMN_NAME as `columnName`,COLUMN_COMMENT as `columnComment` from %v where table_schema = '%v' and table_name in '%v' order by ORDINAL_POSITION", o, s, t)
	}
	getTableCharacterSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT REGEXP_SUBSTR(TABLE_COLLATION, '^[^_]+') AS `character` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME='%v'", o, s, t)
	}
	getTableCollationSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT TABLE_COLLATION as `collation` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME='%v'", o, s, t)
	}
	getTableConstraintsSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT tc.CONSTRAINT_NAME as `name`,cc.CHECK_CLAUSE as `body` FROM %v AS tc JOIN information_schema.CHECK_CONSTRAINTS AS cc ON tc.CONSTRAINT_NAME = cc.CONSTRAINT_NAME WHERE tc.TABLE_SCHEMA = '%v' AND tc.TABLE_NAME = '%v' AND tc.CONSTRAINT_TYPE = 'CHECK'", o, s, t)
	}
	getSchemaDefaultCharacterSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT DEFAULT_CHARACTER_SET_NAME as `character` FROM %v where SCHEMA_NAME='%v'", o, s)
	}
	getSeqBodySql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT `db` AS `schema`,`name` AS `name`,`minvalue` AS `minValue`,`maxvalue` AS `maxValue`,`increment` AS `incrementBy`,`cycle_flag` AS `cycleFlag`,`order_flag` AS `orderFlag`,`cache_num` AS `cacheSize`,`start_with` AS `startValue` FROM %v WHERE `db`='%v' and `name`='%v'", o, s, t)
	}
	getGIpkSql = func(o, s, t string) string {
		return fmt.Sprintf("select VARIABLE_VALUE as `value` from %v where Variable_name='%v'", o, s)
	}
	getLobColumnSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT `COLUMN_NAME` as `columnName`,`DATA_TYPE` as `columnType` FROM %v WHERE TABLE_SCHEMA = '%v'  AND TABLE_NAME = '%v' AND DATA_TYPE IN ('tinyblob', 'blob', 'mediumblob', 'longblob')", o, s, t)
	}
	getBigColumnSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT `COLUMN_NAME` as `columnName`,`DATA_TYPE` as `columnType` FROM %v WHERE TABLE_SCHEMA = '%v'  AND TABLE_NAME = '%v' AND DATA_TYPE in ('varchar','text','mediumtext','longtext')  AND CHARACTER_MAXIMUM_LENGTH > 1000", o, s, t)
	}
	getColumnMetaSql = func(o, s, t string) string {
		return fmt.Sprintf("select table_Schema as databaseName,table_name as tableName,COLUMN_NAME as columnName,DATA_TYPE as columnType,CHARACTER_MAXIMUM_LENGTH as charLength,COLUMN_TYPE as dataType,NUMERIC_PRECISION as dataPrecision,NUMERIC_SCALE as dataScale,ORDINAL_POSITION as columnSeq,IS_NULLABLE as isNull,CHARACTER_SET_NAME as charset,COLLATION_NAME as collationName,COLUMN_COMMENT as columnComment,REPLACE(REPLACE(COLUMN_DEFAULT, 'CHARACTER SET utf8mb4', ''), 'CHARACTER SET utf8', '') as columnDefault,EXTRA as autoIncrement,GENERATION_EXPRESSION as virtualBody from %v where table_schema in ('%v') and table_name in ('%v') order by ORDINAL_POSITION", o, s, t)
	}
	getIndexStatisticsMetaSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT table_schema as `databaseName`,table_name as `tableName`,NON_UNIQUE as `uniqueType`,INDEX_NAME as `indexName`,SEQ_IN_INDEX as `columnSeq`,COLUMN_NAME as `columnName`,SUB_PART as `prefix`,CARDINALITY as `cardinality` FROM %v where table_schema = '%v' and table_name = '%v' order by INDEX_NAME,SEQ_IN_INDEX", o, s, t)
	}
	getIndexColumnDistinctMetaSql = func(o, s, t string) string {
		return fmt.Sprintf("select t.n_rows AS `tableRows`,i.index_name AS `indexName`,i.stat_name AS `statName`,i.stat_value AS `statValue`,i.sample_size AS `sampleSize`,i.stat_description AS `statDescription` from %v on i.database_name=t.database_name and i.table_name=t.table_name where i.database_name='%v' and i.table_name='%v'", o, s, t)
	}
	getTablePartitionTypeMetaSql = func(o, s, t string) string {
		return fmt.Sprintf("select distinct concat(PARTITION_METHOD,',',IFNULL(SUBPARTITION_METHOD,'')) from %v where table_schema='%v' and table_name='%v' and PARTITION_METHOD is not null", o, s, t)
	}
	getTablePartitionSumMetaSql = func(o, s, t string) string {
		return fmt.Sprintf("select count(1) AS `sum` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME = '%v' and PARTITION_METHOD is not null", o, s, t)
	}
	getTablePartitionMetaSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT `TABLE_SCHEMA` AS `schema`,`TABLE_NAME` AS `table`,`PARTITION_NAME` AS `firstPartName`,`SUBPARTITION_NAME` AS `subPartName`,`PARTITION_ORDINAL_POSITION` AS `firstPartSeq`,`SUBPARTITION_ORDINAL_POSITION` AS `subPartSeq`,`PARTITION_METHOD` AS `firstPartMeth`,`SUBPARTITION_METHOD` AS `subPartMeth`,`PARTITION_EXPRESSION` AS `firstPartColumn`,`SUBPARTITION_EXPRESSION` AS `subPartColumn`,`PARTITION_DESCRIPTION` as `partitionRules`,`PARTITION_COMMENT` as `partComment` FROM %v WHERE `table_schema` = '%v' AND `table_name` = '%v' AND `PARTITION_NAME` IS NOT NULL ORDER BY `PARTITION_ORDINAL_POSITION`,`SUBPARTITION_ORDINAL_POSITION`", o, s, t)
	}
	getFullAvgRowsSizeSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT `AVG_ROW_LENGTH` as `AvgRowLength` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME = '%v'", o, s, t)
	}
	getFullIndexSizeMBSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT ROUND(SUM(INDEX_LENGTH) / 1048576, 2) AS `indexSizeMB` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME = '%v'", o, s, t)
	}
	getFullDataSizeMBSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT ROUND(SUM(DATA_LENGTH) / 1048576, 2) AS `dataSizeMB` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME = '%v'", o, s, t)
	}
	getFullRowsSizeSql = func(o, s, t string) string {
		return fmt.Sprintf("SELECT TABLE_ROWS as `tableRows` FROM %v WHERE TABLE_SCHEMA = '%v' AND TABLE_NAME = '%v'", o, s, t)
	}
	SetSessionSqlLogBinOffSql = func(s string) string {
		return fmt.Sprintf("SET session sql_log_bin = %v", s)
	}
	SetSessionSqlModeSql = func(s string) string {
		return fmt.Sprintf("SET session sql_mode = '%v'", s)
	}
	getMaxConnections = func(o, s, t string) string {
		return fmt.Sprintf("select VARIABLE_VALUE-(select count(1) from information_schema.processlist) as `maxAvailableConnection` from %v where variable_name = 'max_connections'", o)
	}
	getServerCharacter = func(o, s, t string) string {
		return fmt.Sprintf("select VARIABLE_VALUE as `character` from %v where VARIABLE_NAME='character_set_server'", o)
	}
)

var (
	createSeqBodySql = func(s, t, mi, ma, in, st, ca, or, cy string) string {
		return fmt.Sprintf("use %v; \n"+
			"CREATE SEQUENCE `%v`.`%v` \n"+
			"\t MINVALUE %v \n"+
			"\t MAXVALUE %v \n"+
			"\t INCREMENT BY %v \n"+
			"\t START WITH %v \n "+
			"\t %v %v %v; \n", s, s, t, mi, ma, in, st, ca, or, cy)
	}
	dropSeqSql = func(s, t string) string {
		return fmt.Sprintf("DROP SEQUENCE IF EXISTS `%v`.`%v`;", s, t)
	}
	dropTableSql = func(s, t string) string {
		return fmt.Sprintf("DROP TABLE IF EXISTS `%v`.`%v`;", s, t)
	}
	renameTableSql = func(s, t, ss, tt string) string {
		return fmt.Sprintf("RENAME TABLE `%v`.`%v` TO `%v`.`%v`;", s, t, ss, tt)
	}
	createDatabaseSql = func(s string) string {
		return fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%v`;", s)
	}
	likeTableSql = func(s, t, ss, tt string) string {
		return fmt.Sprintf("CREATE TABLE `%v`.`%v` LIKE `%v`.`%v`;", s, t, ss, t)
	}
	truncateTableSql = func(s, t string) string {
		return fmt.Sprintf("TRUNCATE TABLE `%v`.`%v`;", s, t)
	}
	truncatePartSql = func(s, t, p string) string {
		return fmt.Sprintf("ALTER TABLE `%v`.`%v` TRUNCATE PARTITION `%v`;", s, t, p)
	}
	useSchemaSql = func(s string) string {
		return fmt.Sprintf("USE `%v`;", s)
	}
	analyzeTableSql = func(t string) string {
		return fmt.Sprintf("ANALYZE TABLE `%v`;", t)
	}
)
